(defpackage :com.qingluan.hello-qingluan
  (:use :cl )
  (:export :component-p
	   :directory-pathname-p
	   :pathname-as-directory
	   :directory-wildcard
	   :list-directory
	   :print-dire))

(defun component-p (name)
  (and name (not (eql name :unspecific))))

(defun directory-pathname-p (name)
  (and 
   (not (component-p (pathname-name name)))
   (not (component-p (pathname-type name)))
   name))

(defun pathname-as-directory (name)
  (let ((pathname name))
    (when (wild-pathname-p pathname )
      (error "can't reliably convert wild pathnames."))
    (if (not  (directory-pathname-p pathname))    
	(make-pathname
	 :directory (append (or (pathname-directory pathname) (list :relative))
			(list (file-namestring pathname)))
	 :name nil
	 :type nil
	 :defaults pathname)
	pathname)))

(defun directory-wildcard(path)
  (make-pathname 
   :name :wild
   :type #-clist :wild  #+clisp nil
   :defaults (pathname-as-directory path)))
;;
;;this is a main function for list file in  directory  and pro-directories   
(defun list-directory (path)
  (when (wild-pathname-p path)
    (error "can only list concrete pathnames ."))
  (directory (directory-wildcard path ) :directories t)))

(defun print-dire (path)
	   (let ((a 0 )
		 (list (list-directory path)))
	     (setf xx #'(lambda  () (incf a )))
	     (loop for i in list do
		  (format t "No.~2d ~a ~%" (funcall xx) i))))
		 


;;map all pro-directory 
(defun walk-directory (dirname fn &key directories (test (constantly t)))
  (labels
      ((walk (name)
	 (cond 
	   ((directory-pathname-p name)
	    (when (and directories (funcall test name))
	      (funcall fn name ))
	    (dolist (x (list-directory name )) (walk x )))
	   ((funcall test name ) ( funcall fn name)))))
    (walk (pathname-as-directory dirname))))

